﻿using System;
using System.Collections.Generic;
using System.Linq;
using SinBiota.Model.Business.PersistenceServices.Interfaces;
using SinBiota.Model.Entities;
using SinBiota.Model.Persistence.Repositories.Interfaces;

namespace SinBiota.Model.Business.PersistenceServices.Implementation
{
    public class TaxonPersistenceServices : ITaxonPersistenceServices
    {
        private readonly ITaxonRepository _taxonRepository;
        private readonly ITaxonReferenceRepository _taxonReferenceRepository;

        public TaxonPersistenceServices(ITaxonRepository taxonRepository, ITaxonReferenceRepository taxonReferenceRepository)
        {
            _taxonRepository = taxonRepository;
            _taxonReferenceRepository = taxonReferenceRepository;
        }

        public Taxon FindById(int id)
        {
            return _taxonRepository.FindById(id);
        }

        public IList<Taxon> FindByNameAndRank(string name, string taxonomicRank)
        {
            return _taxonRepository.FindByEqRestrictionListResult(x => x.Name, name).Where(x => x.Rank == taxonomicRank).ToList();
        }


        public IList<Taxon> FindAncestors(Taxon taxon)
        {
            return _taxonRepository.FindAncestors(taxon);
        }

        public IList<Taxon> FindAllRootNodes()
        {
            return _taxonRepository.FindAllRootNodes();
        }

        public IList<Taxon> FindChildren(Taxon taxon)
        {
            return _taxonRepository.FindChildren(taxon);
        }

        public IList<Taxon> FindByNameStartswith(string term)
        {
            return _taxonRepository.FindByPreffix(x => x.Name, term);
        }

        public IList<Taxon> FindByNameStartswithAndRank(string term, string rank)
        {
            return _taxonRepository.FindByPreffix(x => x.Name, term).Where(x => x.Rank == rank).ToList();
        }

        public IList<Taxon> FindByNameLike(string term)
        {
            return _taxonRepository.FindByInffix(x => x.Name, term);
        }

        public void Save(Taxon taxon)
        {
            _taxonRepository.Save(taxon);
        }

        public void SaveTaxonReference(TaxonReference taxonReference)
        {
            _taxonReferenceRepository.Save(taxonReference);
        }

        public TaxonReference FindReferenceByExactNameOrCreate(string title)
        {
            var taxonReference = _taxonReferenceRepository.FindByEqRestrictionUniqueResult(x => x.Title, title);
            if (taxonReference == null)
            {
                taxonReference = new TaxonReference{Title = title};
                SaveTaxonReference(taxonReference);
            }
            return taxonReference;
        }
    }
}